package battleship;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;


@WebServlet("/LoginHandler")
public class LoginHandler extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// Kontrolli, kas see autentimine algatati ikka selles sessioonis
		String storedState = (String)request.getSession().getAttribute("FBState");
		String offeredState = request.getParameter("state");
		if (storedState == null || offeredState == null || !storedState.equals(offeredState)) {
			// TODO näita vealehekülge
			throw new ServletException("Mingi kahtlane värk state'iga"); 
		}
		
		// Küsi FB-lt kasutaja andmed vastavalt sellele koodile, mis anti parameetriks
		String code = request.getParameter("code");
		String userAccessToken = getUserAccessToken(code);
		String userInfoJSON = getUserInfo(userAccessToken);
		String username="vale"; 
		
		request.setAttribute("FBCode", code);
		request.setAttribute("FBUserAccessToken", userAccessToken);
		request.setAttribute("FBUserInfoJSON", userInfoJSON);
		
		 JSONObject json;
		try {
			json = (JSONObject)new JSONParser().parse(userInfoJSON);
		    System.out.println("name=" + json.get("name"));
		    username=(String) json.get("name");
		    System.out.println(username);
		    request.setAttribute("username", username);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		
//		    Gson gson = new Gson();
//			String row = gson.fromJson(userInfoJSON, null);
//			System.out.println(row);
			
		//String name= userInfoJSON.name;
		
		
		
		  System.out.println("LoginServlet: starting");
            try {
                CreateDatabase.create();
                Databasetest.addScores("Kalle", 1);
            } catch (Exception e) {
                    e.printStackTrace();
                }
	      //  response.setContentType("text/html");
	      //  PrintWriter out = response.getWriter();

	        User user; String userUsername;
	        int i = 0;
	        // find the user if he/she exists
	        while ((user = Context.users[i]) != null) {
	            userUsername = user.getUsername();
	            if (userUsername.equals(username)) {
	                // check if user is online

	                // if user isn't online, return user's id
	                user.lastSeen = new Date(); // mark user as being online now
	                user.online = true;
	                Context.onlineUsers.add(user);
	                user.checkIfOnline(); // start heartbeat to check if user is online

                    System.out.println("LogInServlet: finished");
                    request.setAttribute("id", user.id);
                    request.setAttribute("Name", userInfoJSON);
                    request.getRequestDispatcher("LoginHandler.jsp").forward(request, response);

	                return;
	            }
	            i++;
	        }
	        // if you've reached this point, then this is the user's first visit
	        // create user, add them to user list
	        System.out.println("LoginS: creating a user!");
	        user = new User();
	        Context.users[user.id] = user;
	        UserIdTokenHashMap.idTokenMap.put(userAccessToken,user.id);
	        user.username = username;
	        Context.onlineUsers.add(user);

            try {
                CreateDatabase.create();
                Databasetest.addScores("Kalle", 1);
            } catch (Exception e) {
                e.printStackTrace();
            }
	      
	        System.out.println("LogInServlet: finished");
	        request.setAttribute("id", user.id);
		
		

		request.setAttribute("Name", userInfoJSON);
		request.getRequestDispatcher("LoginHandler.jsp").forward(request, response);
	}
	
	private String getUserAccessToken(String code) throws IOException {
		// Küsi Facebookilt vastus
		String content = getStringFromUrl("https://graph.facebook.com/oauth/access_token" +
				"?client_id="     + FBConstants.APP_ID + 
				"&redirect_uri="  + FBConstants.REDIRECT_URI + 
				"&client_secret=" + FBConstants.APP_SECRET + 
				"&code="          + code);
		
		// nopi vastusest välja user token
		String[] pairs = content.split("\\&");
	    for (int i = 0; i < pairs.length; i++) {
		    String[] fields = pairs[i].split("=");
		    String name = URLDecoder.decode(fields[0], "UTF-8");
		    String value = URLDecoder.decode(fields[1], "UTF-8");
		    if (name.equals("access_token")) {
		    	return value;
		    }
	    }
	    
		return null;
	}
	
	private String getUserInfo(String userAccessToken) throws IOException {
		return getStringFromUrl("https://graph.facebook.com/me?access_token=" + userAccessToken);
	}
	
	private String getStringFromUrl(String urlString) throws IOException {
		URL url = new URL(urlString);
		
		HttpURLConnection conn = (HttpURLConnection)url.openConnection();
		try {
			conn.setRequestMethod("GET");
			conn.setDoOutput(true);
			conn.setReadTimeout(10000);
			conn.connect();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			
			StringBuilder sb = new StringBuilder();
	        String line;
	        while ((line = reader.readLine()) != null)
	        {
	            sb.append(line + '\n');
	        }
	        
	        return sb.toString();
		}
		finally {
			conn.disconnect();
		}
	}
		
}